package com.gao.q_readwritelock.c;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/*
    你需要实现一个高效的缓存，同一时刻它允许多个用户读，但只允许一个用户写，以此来保持它的完整性，你会怎样去实现它？
*/
public class App {
    private Map<String, Object> cache = new HashMap<>();
    private static ReadWriteLock rwl = new ReentrantReadWriteLock();

    public Object getData(String key) {
        Object value = null;
        rwl.readLock().lock();
        try {
            value = cache.get(key);
            if (value == null) {
                // 流程走到这里，意味着，要去持久层查询数据。
                // 读锁升级为写锁，必须先释放读锁，再添加写锁，否则会引起死锁
                rwl.readLock().unlock();
                rwl.writeLock().lock();
                try {
                    if (value == null) {

                        // 模拟查询
                        value = "foo";
                        // 放入缓存中
                        cache.put(key, value);
                    }
                    // 锁降级，先获取读锁，再释放写锁
                    // 注意不能把改行代码写到释放写锁之后，否则有可能会有线程释放一个已经没有读锁的锁
                    rwl.readLock().lock();
                } finally {
                    rwl.writeLock().unlock();
                }
            }
        } finally {
            rwl.readLock().unlock();
        }
        return value;
    }

    public static void main(String[] args) {
    }
}
